from django.conf import settings
from django.contrib.auth.models import User
from django.db import models, transaction
from django.utils.translation import ugettext_lazy as _
from django_extensions.db.models import CreationDateTimeField
from positions.fields import PositionField
from opinion_extractor.generic_filter.fields import QueryFilterField
import fields
import managers
import utils


class Questionnaire(models.Model):
    title = models.CharField(
        _('title'), 
        db_index=True,
        max_length=200, 
        unique=True
    )
    # TODO: Automaticaly generate slug from title if blank, and add options:
    # help_text='Used for URLs, auto-generated from title if blank',
    # blank=True
    slug = models.SlugField(_('slug'), db_index=True, unique=True)
    # TODO: Add a markup language (markdown maybe?) and a WYSIWYM/G editor
    # TODO: Add a description_html denormalised field
    # TODO: Add a description_txt denormalised field (for e-mails)
    # TODO: Uncomment  description field
    #    description = models.TextField(
    #        _('description'),
    #        blank=True,
    #        null=True
    #    )
    # TODO: Track via persistent cache sample sizes for each day
    # TODO: Track via persistent cache the date when sample size first became
    # >= min_sample_size
    min_sample_size = models.PositiveIntegerField(_('minimum sample size'))
    population_filter = QueryFilterField(
        _('filter population by fields'),
        valid_field_names_func=utils.get_valid_field_names_func
    )
    
    # Meta data
    created_by = models.ForeignKey(
        User,
        verbose_name=_('created by'),
        editable=False
    )
    created_on = CreationDateTimeField(
        _('created on'),
        db_index=True
    )
    PUBLISH_STATUS_CHOICES = (
        ('D', _('Draft')), 
        ('L', _('Live')),
        ('R', _('Revoked')), 
    ) 
    publish_status = models.CharField(
        _('publish status'),
        max_length=1,
        blank=True,
        db_index=True,
        editable=False,
        choices=PUBLISH_STATUS_CHOICES, 
        default='D' # Questionnaires should be in draft state when created
    )
    published_on = models.DateTimeField(
        _('published on'),
        blank=True,
        db_index=True,
        editable=False,
        null=True
    )
    num_questions = models.PositiveIntegerField(
        _('number of questions'),
        editable=False,
        default=0
    )
    
    objects = models.Manager()
    published = managers.LiveQuestionnaireManager()
    
    class Meta:
        get_latest_by = 'published_on'
        ordering = ('title',)
        permissions = ( ('answer_questionnaire', 'Can answer questionnaire'), )
        verbose_name = _('questionnaire')
        verbose_name_plural = _('questionnaires')

    def __unicode__(self):
        return self.title


class Question(models.Model):
    title = models.CharField(
        _('question title'), 
        max_length=200, 
        db_index=True
    )
    questionnaire = models.ForeignKey(
        Questionnaire,
        verbose_name=_('questionnaire'),
        related_name='questions'
    )
    answers = fields.AnswersField(_('answers'))
    num_answers = models.PositiveIntegerField(
        _('number of answers'),
        editable=False,
    )
    position = PositionField(
        _('position'),
        db_index=True,
        unique_for_field='questionnaire'
    )

    class Meta:
        verbose_name = _('question')
        verbose_name_plural = _('questions')
        ordering = ('position',)
        unique_together = (
            ('questionnaire', 'title'),
        )

    def __unicode__(self):
        return self.title

    @transaction.commit_on_success 
    def save(self, *args, **kwargs):
        self.num_answers = len(self.answers)
        super(Question, self).save(*args, **kwargs)
